export default class Util {
    static timer() {
        let _on = false;
        let _timer = null;
        let _func = null;
        let _interval = 0;

        function _start() {
            if (_on) {
                _func.call(null);
                _timer = window.setTimeout(_start, _interval);
            }
        }

        return {
            set(func, interval) {
                _func = func;
                _interval = interval;
                if (!_on) {
                    _on = true;
                    _start();
                } else {
                    window.clearTimeout(_timer);
                    _on = true;
                    _start();
                }
            },
            clear() {
                _on = false;
                _timer = null;
                _func = null;
                _interval = 0;
            },
        }
    }

    static getStyle(elem, attr) {
        if (elem.currentStyle) {   //IE浏览器
            return elem.currentStyle[attr];
        } else {    //chrome、firefox等浏览器
            return getComputedStyle(elem, null)[attr];
        }
    }

    static animate(elem, json, callback, spd) {
        if (elem.timer) {
            elem.timer.clear();
        }

        elem.timer = Util.timer();

        const result = JSON.parse(JSON.stringify(json));

        for (let attr in json) {
            result[attr] = false;
        }

        function setWithUnit(attr, unit, ...args) {

            if (result[attr]) {
                return;
            }

            let currentStyle = parseFloat(Util.getStyle(elem, attr));
            let speed;
            if (attr == args[0] || attr == args[1] || attr == args[2]) {
                if (unit === 'vw') {
                    currentStyle = currentStyle * 100 / document.body.clientWidth;
                } else if (unit === 'vh') {
                    currentStyle = currentStyle * 100 / document.body.clientHeight;
                }
                speed = (json[attr] - currentStyle) / 10;
                speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
                speed = speed > 0 ? spd || speed : -spd || speed;
                if (speed > 0 && currentStyle + speed >= json[attr]) {
                    elem.style[attr] = json[attr] + unit;
                    result[attr] = true;
                } else if (speed < 0 && currentStyle + speed <= json[attr]) {
                    elem.style[attr] = json[attr] + unit;
                    result[attr] = true;
                } else {
                    elem.style[attr] = (currentStyle + speed) + unit;
                    result[attr] = false;
                }
            }
        }

        elem.timer.set(() => {
            for (let attr in json) {
                let currentStyle = parseFloat(Util.getStyle(elem, attr));

                if (isNaN(currentStyle)) {
                    elem.style[attr] = json[attr];
                    result[attr] = true;
                }

                let speed;
                if (attr == 'opacity') {
                    speed = json[attr] - currentStyle > 0 ? 0.1 : -0.1;
                    if (speed > 0 && currentStyle + speed >= json[attr]) {
                        elem.style[attr] = json[attr];
                        result[attr] = true;
                    } else if (speed < 0 && currentStyle + speed <= json[attr]) {
                        elem.style[attr] = json[attr];
                        result[attr] = true;
                    } else {
                        elem.style[attr] = currentStyle + speed;
                        result[attr] = false;
                    }
                }

                setWithUnit(attr, 'vw', 'width', 'left', 'right');
                setWithUnit(attr, 'vh', 'height', 'top', 'bottom');
            }

            let flag = true;
            for (let attr in result) {
                if (result[attr] == false) {
                    flag = false;
                    break;
                }
            }
            if (flag) {
                elem.timer.clear();
                callback && callback();
            }
            // console.log('动画定时器正在运行！！！');
        }, 32);
    }
}